#include <iostream>
#include <fstream>
#include "./tinyxml/tinyxml.h"
#include <string.h>
#include <cstdlib> 
#include <list>
#include "AdministradorDeNiveles.h"

using namespace std;

string preguntarIdNivel() {
	string nombre = "";
	
	do {
		cout << "ID del nivel: ";
		cin >> nombre;
		if (nombre == "")
			cout << "ID invalido, intente nuevamente" << endl;
		
	} while (nombre == "");
	
	return nombre;
}

string preguntarDuracionNivel() {
	string duracion = "";
	
	do {
		cout << "Duracion del nivel: ";
		cin >> duracion;
		if (duracion == "" || atoi(duracion.c_str()) < 0)
			cout << "Duracion invalida, intente nuevamente" << endl;
		
	} while (duracion == "" || atoi(duracion.c_str()) < 0);
	
	return duracion;
}

string preguntarObjeto() {
	system("clear");
	string opc = "";
	string objeto;
	bool opcOk = true;
	
	do {
		cout << "Seleccione la opcion adecuada para insertar un objeto. 0 para terminar y guardar el nivel" << endl;
		cout << "Nota 1: Debe haber al menos un cerdo, una catapulta y un monticulo" << endl;
		cout << "Nota 2: Si se elije usar un fondo, este debe ser un archivo existente en la ruta de imagenes. Si no se encuentra se usara uno por defecto" << endl;
		cout << endl;
		cout << "1. Caja de madera" << endl;
		cout << "2. Caja de metal" << endl;
		cout << "3. Manzana" << endl;
		cout << "4. Banana" << endl;
		cout << "5. Cerdo" << endl;
		cout << "6. Catapulta" << endl;
		cout << "7. Monticulo" << endl;
		cout << "8. Fondo" << endl;
		cout << endl;
		cout << "0. Salir" << endl;
		
		cin >> opc;
		
		if ((opc == "" || (opc != "1" && opc != "2" && opc != "3" && opc != "4" && opc != "5" && opc != "6" && opc != "7" && opc != "8" && opc != "0"))) {
			cout << "Opcion invalida, intente nuevamente" << endl;
			opcOk = false;
		}
		else opcOk = true;
		
	} while (!opcOk);
	
	int opcInt = atoi(opc.c_str());
	
	switch (opcInt) {
		case 1:	objeto = "Caja"; break;
		case 2:	objeto = "CajaMetal"; break;
		case 3:	objeto = "Manzana";	break;
		case 4:	objeto = "Banana"; break;
		case 5:	objeto = "Cerdo"; break;
		case 6:	objeto = "Catapulta"; break;
		case 7: objeto = "Monticulo"; break;
		case 8:	objeto = "Fondo"; break;
		case 0:	objeto = "0"; break;
		default: break;
	}
	
	return objeto;
}

string preguntarPosicionX() {
	string pos;
	do {
		cout << "Posicion en X: ";
		cin >> pos;
		if (pos == "" || atoi(pos.c_str()) < 0)
			cout << "Posicion invalida, intente nuevamente" << endl;
		
	} while (pos == "" || atoi(pos.c_str()) < 0);
	
	return pos;
}

string preguntarPosicionY() {
	string pos;
	do {
		cout << "Posicion en Y: ";
		cin >> pos;
		if (pos == "" || atoi(pos.c_str()) < 0)
			cout << "Posicion invalida, intente nuevamente" << endl;
		
	} while (pos == "" || atoi(pos.c_str()) < 0);
	
	return pos;
}

string preguntarArchivoFondo() {
	string archFondo;
	
	cout << "Ingrese el nombre del archivo para usar como fondo (sin extension): ";
	cin >> archFondo;
	
	return archFondo;
}

void agregarNivelAlMundo(string idNivel, string archivo) {
	AdministradorDeNiveles admin;
	admin.agregarNivel(idNivel, archivo, "b");
}

TiXmlElement* agregarObjeto(string objeto, string posX, string posY) {
	TiXmlElement* elemento = new TiXmlElement("objeto");
	elemento->SetAttribute("tipo", objeto);
			
	TiXmlElement *elementPosX = new TiXmlElement("posicionx");
	TiXmlText *textX = new TiXmlText(posX);
	elementPosX->LinkEndChild(textX);

	TiXmlElement *elementPosY = new TiXmlElement("posiciony");
	TiXmlText *textY = new TiXmlText(posY);
	elementPosY->LinkEndChild(textY);
	
	elemento->LinkEndChild(elementPosX);
	elemento->LinkEndChild(elementPosY);
	
	return elemento;
}

void crear(){
	string nombreArchivo;
	string nombreObjeto;
	string duracionNivel;
	string posicionx;
	string posiciony;
	system("clear");
	
	cout << "Creando un nuevo nivel" << endl;
	string idNivel = preguntarIdNivel();
	nombreArchivo = "common/nivel" + idNivel + ".xml";
	
	duracionNivel = preguntarDuracionNivel();

	TiXmlDocument doc;
    TiXmlDeclaration *decl = new TiXmlDeclaration( "1.0", "", "" );
    doc.LinkEndChild(decl);
    
    TiXmlElement *elementNivel = new TiXmlElement("nivel");
    TiXmlElement *elementObjeto;
    
	elementNivel->SetAttribute("duracion", duracionNivel);
	doc.LinkEndChild(elementNivel);
    	
	do {
		nombreObjeto = preguntarObjeto();
		if (nombreObjeto != "0") {
			if (nombreObjeto == "Fondo") {
				nombreObjeto = preguntarArchivoFondo();
				posicionx = "0";
				posiciony = "0";
				TiXmlElement *primero = elementNivel->FirstChildElement();
				TiXmlElement *nodoFondo = agregarObjeto(nombreObjeto, posicionx, posiciony);
				elementNivel->InsertBeforeChild(primero, *nodoFondo);

			}
			else {
				posicionx = preguntarPosicionX();
				posiciony = preguntarPosicionY();
				elementNivel->LinkEndChild(agregarObjeto(nombreObjeto, posicionx, posiciony));
			}
		}
	} while (nombreObjeto != "0");
	
	// Se agrega nido
	elementNivel->LinkEndChild(agregarObjeto("Nido", "1200", "500"));
	
	// Se agrega reloj
	elementNivel->LinkEndChild(agregarObjeto("Reloj", "2000", "0"));

	// Se agrega piso
	elementNivel->LinkEndChild(agregarObjeto("Piso", "0", "0"));
	

	agregarNivelAlMundo(idNivel, nombreArchivo);
	doc.SaveFile(nombreArchivo);
}

int main(int argc, char** argv)
{	
	
    crear();
	
	return 0;
}
